package MyGui;

import java.awt.*;
import java.awt.event.*;
import java.lang.Object;
import javax.swing.*;
import java.util.*;

import DistSys.*;
import Element.*;
import Element.Geom.AbsElemGeom;

public class DataModifyDlg extends MyDlgFrame implements ActionListener,
                                                         WindowListener {
    private ZoneComboBox comboZone;
    private JComboBox comboType;

    private static final int DATA_REPLACE   =  0;
    private static final int DATA_MULTIPLY  =  1;
    private static final int DATA_ADD       =  2;
    private static final int DATA_RESTORE   =  3;
    private static final int DATA_CUSTOMIZE =  4;
    private static final int DATA_RANDOM    =  5;
    private static final int NAME           =  6;
    private static final int DESCRIPTION    =  7;
    private static final int TEMPLATE       =  8;
    private static final int TEMPLATE_DESC  =  9;
    private static final int TEXT           = 10;
    private JButton[] aButton   = new JButton[11];

    private JComboBox comboDataField;
    private JTextField tfDataReplace;
    private JTextField tfDataMultiply;
    private JTextField tfDataAdd;
    private JTextField tfDataRandomMin;
    private JTextField tfDataRandomMax;

    private JTextField tfName;
    private JTextField tfDescription;
    private JComboBox comboTemplate;

    private JTextField tfTextSize;
    private JCheckBox checkTextName;
    private JCheckBox checkTextDesc;
    private JList[] alstTextIndex;

    /**
     * Creates a <code>DataSumDlg</code>.
     */
    public DataModifyDlg(MainFrame parent) {
        super( parent, "Data Modification Tools");
        setSize(490, 415);
        Container contentPane = getContentPane();
        contentPane.setLayout(new BorderLayout());

        // Initialize components
        comboZone = new ZoneComboBox();
        comboZone.setRequestFocusEnabled(true);
        JLabel lblZone = new JLabel("Area:");
        lblZone.setDisplayedMnemonic('A');
        lblZone.setLabelFor(comboZone);

        comboType = new JComboBox(SysConst.ssType);
        comboType.setRequestFocusEnabled(true);
        comboType.addActionListener(this);
        JLabel lblType = new JLabel("Component Type:");
        lblType.setDisplayedMnemonic('T');
        lblType.setLabelFor(comboType);

        // Construct north panel
        JPanel northPanel = new JPanel(gridBagLayout);
        contentPane.add(northPanel, BorderLayout.NORTH);

        add(northPanel, lblZone, 0, 0, 1, 1, 0, 0,
            GridBagConstraints.WEST, GridBagConstraints.NONE, GAP, GAP, 0, 0);
        add(northPanel, comboZone, 1, 0, 1, 1, 100, 0,
            GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
            GAP, GAP, 0, GAP);

        add(northPanel, lblType, 0, 1, 1, 1, 0, 0,
            GridBagConstraints.WEST, GridBagConstraints.NONE, GAP, GAP, GAP, 0);
        add(northPanel, comboType, 1, 1, 1, 1, 100, 0,
            GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
            GAP, GAP, GAP, GAP);

        // Construct center panel
        JTabbedPane tabbedPane = new JTabbedPane();
        contentPane.add(tabbedPane, BorderLayout.CENTER);

        tabbedPane.addTab("Data", createDataTab());
        tabbedPane.addTab("General", createGeneralTab());
        tabbedPane.addTab("Text", createTextTab());

        addWindowListener(this);
    }

    public void setArea(double dZone) {
        comboZone.setSelectedZone(dZone);
    }

    private Component createDataTab() {
        JPanel panel = new JPanel(gridBagLayout);

        // Initialize components
        comboDataField = new JComboBox(SysConst.ssDataField);
        comboDataField.setRequestFocusEnabled(true);
        JLabel lblDataField = new JLabel("Data Field:");
        lblDataField.setDisplayedMnemonic('F');
        lblDataField.setLabelFor(comboDataField);

        tfDataReplace = new JTextField("0", 2);
        JLabel lblDataReplace = new JLabel("Replacer:");
        lblDataReplace.setDisplayedMnemonic('P');
        lblDataReplace.setLabelFor(tfDataReplace);
        aButton[DATA_REPLACE] = new JButton("Replace Data");
        aButton[DATA_REPLACE].setMnemonic('L');
        aButton[DATA_REPLACE].addActionListener(this);

        tfDataMultiply = new JTextField("1", 2);
        JLabel lblDataMultiply = new JLabel("Multiplier:");
        lblDataMultiply.setDisplayedMnemonic('U');
        lblDataMultiply.setLabelFor(tfDataMultiply);
        aButton[DATA_MULTIPLY] = new JButton("Multiply Data");
        aButton[DATA_MULTIPLY].setMnemonic('M');
        aButton[DATA_MULTIPLY].addActionListener(this);

        tfDataAdd = new JTextField("0", 2);
        JLabel lblDataAdd = new JLabel("Adder:");
        lblDataAdd.setDisplayedMnemonic('E');
        lblDataAdd.setLabelFor(tfDataAdd);
        aButton[DATA_ADD] = new JButton("Add to Data");
        aButton[DATA_ADD].setMnemonic('D');
        aButton[DATA_ADD].addActionListener(this);

        aButton[DATA_RESTORE] = new JButton("Restore Default");
        aButton[DATA_RESTORE].setMnemonic('S');
        aButton[DATA_RESTORE].addActionListener(this);

        aButton[DATA_CUSTOMIZE] = new JButton("Make Custom");
        aButton[DATA_CUSTOMIZE].setMnemonic('C');
        aButton[DATA_CUSTOMIZE].addActionListener(this);

        tfDataRandomMin = new JTextField("0", 4);
        JLabel lblDataRandomMin = new JLabel("Min Value:");
        lblDataRandomMin.setDisplayedMnemonic('N');
        lblDataRandomMin.setLabelFor(tfDataRandomMin);

        tfDataRandomMax = new JTextField("1", 4);
        JLabel lblDataRandomMax = new JLabel("Max Value:");
        lblDataRandomMax.setDisplayedMnemonic('X');
        lblDataRandomMax.setLabelFor(tfDataRandomMax);

        aButton[DATA_RANDOM] = new JButton("Assign Random Data");
        aButton[DATA_RANDOM].setMnemonic('R');
        aButton[DATA_RANDOM].addActionListener(this);

        // Construct panel
        add(panel, lblDataField, 0, 0, 1, 1, 0, 0,
            GridBagConstraints.WEST, GridBagConstraints.NONE, GAP, GAP, 0, 0);
        add(panel, comboDataField, 1, 0, 1, 1, 100, 0,
            GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
            GAP, GAP, 0, GAP);

        // Construct adjust panel
        JPanel adjustPanel = new JPanel(gridBagLayout);
        adjustPanel.setBorder(BorderFactory.createTitledBorder(
            BorderFactory.createEtchedBorder(), " Adjust Data "));
        add(panel, adjustPanel, 0, 1, 2, 1, 100, 0,
            GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
            GAP, GAP, 0, GAP);

        add(adjustPanel, lblDataReplace, 0, 0, 1, 1, 0, 0,
            GridBagConstraints.WEST, GridBagConstraints.NONE, 0, GAP, 0, 0);
        add(adjustPanel, tfDataReplace, 1, 0, 1, 1, 50, 0,
            GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
            0, GAP, 0, GAP);
        add(adjustPanel, aButton[DATA_REPLACE], 2, 0, 1, 1, 100, 0,
            GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL,
            0, GAP, 0, GAP);

        add(adjustPanel, lblDataMultiply, 0, 1, 1, 1, 0, 0,
            GridBagConstraints.WEST, GridBagConstraints.NONE, 0, GAP, 0, 0);
        add(adjustPanel, tfDataMultiply, 1, 1, 1, 1, 50, 0,
            GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
            0, GAP, 0, GAP);
        add(adjustPanel, aButton[DATA_MULTIPLY], 2, 1, 1, 1, 100, 0,
            GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL,
            0, GAP, 0, GAP);

        add(adjustPanel, lblDataAdd, 0, 2, 1, 1, 0, 0,
            GridBagConstraints.WEST, GridBagConstraints.NONE, 0, GAP, 0, 0);
        add(adjustPanel, tfDataAdd, 1, 2, 1, 1, 50, 0,
            GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
            0, GAP, 0, GAP);
        add(adjustPanel, aButton[DATA_ADD], 2, 2, 1, 1, 100, 0,
            GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL,
            0, GAP, 0, GAP);

        JPanel adjustBottomPanel = new JPanel(new GridLayout(1, 2, GAP, 0));
        add(adjustPanel, adjustBottomPanel, 0, 3, 3, 1, 100, 0,
            GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
            GAP, GAP, GAP, GAP);

        adjustBottomPanel.add(aButton[DATA_RESTORE]);
        adjustBottomPanel.add(aButton[DATA_CUSTOMIZE]);

        // Construct random panel
        JPanel randomPanel = new JPanel(gridBagLayout);
        randomPanel.setBorder(BorderFactory.createTitledBorder(
            BorderFactory.createEtchedBorder(), " Randomize Data "));
        add(panel, randomPanel, 0, 2, 2, 1, 100, 100,
            GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL,
            GAP, GAP, 0, GAP);

        add(randomPanel, lblDataRandomMin, 0, 0, 1, 1, 0, 0,
            GridBagConstraints.WEST, GridBagConstraints.NONE, 0, GAP, 0, 0);
        tfDataRandomMin.setNextFocusableComponent(tfDataRandomMax);
        add(randomPanel, tfDataRandomMin, 1, 0, 1, 1, 50, 0,
            GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
            0, GAP, 0, GAP);

        add(randomPanel, lblDataRandomMax, 0, 1, 1, 1, 0, 0,
            GridBagConstraints.WEST, GridBagConstraints.NONE, 0, GAP, GAP, 0);
        tfDataRandomMax.setNextFocusableComponent(aButton[DATA_RANDOM]);
        add(randomPanel, tfDataRandomMax, 1, 1, 1, 1, 50, 0,
            GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
            0, GAP, GAP, GAP);

        aButton[DATA_RANDOM].setNextFocusableComponent(comboZone);
        add(randomPanel, aButton[DATA_RANDOM], 2, 0, 1, 2, 100, 0,
            GridBagConstraints.WEST, GridBagConstraints.BOTH,
            0, GAP, GAP, GAP);

        return panel;
    }

    private Component createGeneralTab() {
        JPanel panel = new JPanel(gridBagLayout);

        // Initialize components
        tfName = new JTextField("", 25);
        JLabel lblName = new JLabel("Name:");
        lblName.setDisplayedMnemonic('M');
        lblName.setLabelFor(tfName);
        aButton[NAME] = new JButton("Replace Name");
        aButton[NAME].setMnemonic('N');
        aButton[NAME].addActionListener(this);

        tfDescription = new JTextField("", 25);
        JLabel lblDescription = new JLabel("Description:");
        lblDescription.setDisplayedMnemonic('E');
        lblDescription.setLabelFor(tfDescription);
        aButton[DESCRIPTION] = new JButton("Replace Description");
        aButton[DESCRIPTION].setMnemonic('D');
        aButton[DESCRIPTION].addActionListener(this);

        comboTemplate = new JComboBox();
        comboTemplate.setEnabled(false);
        JLabel lblTemplate = new JLabel("Default Template:");
        lblTemplate.setDisplayedMnemonic('L');
        lblTemplate.setLabelFor(comboTemplate);
        aButton[TEMPLATE] = new JButton("Replace Template");
        aButton[TEMPLATE].setEnabled(false);
        aButton[TEMPLATE].setMnemonic('P');
        aButton[TEMPLATE].addActionListener(this);
        aButton[TEMPLATE_DESC] = new JButton("Replace Template and Description");
        aButton[TEMPLATE_DESC].setEnabled(false);
        aButton[TEMPLATE_DESC].setMnemonic('A');
        aButton[TEMPLATE_DESC].addActionListener(this);

        // Construct name panel
        JPanel namePanel = new JPanel(gridBagLayout);
        namePanel.setBorder(BorderFactory.createTitledBorder(
            BorderFactory.createEtchedBorder(), " Name / Description "));
        add(panel, namePanel, 0, 0, 1, 1, 100, 0,
            GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
            GAP, GAP, 0, GAP);

        add(namePanel, lblName, 0, 0, 1, 1, 0, 0,
            GridBagConstraints.WEST, GridBagConstraints.NONE, 0, GAP, 0, 0);
        add(namePanel, tfName, 1, 0, 1, 1, 100, 0,
            GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
            0, GAP, 0, GAP);
        add(namePanel, aButton[NAME], 2, 0, 1, 1, 0, 0,
            GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL,
            0, GAP, 0, GAP);

        add(namePanel, lblDescription, 0, 1, 1, 1, 0, 0,
            GridBagConstraints.WEST, GridBagConstraints.NONE, 0, GAP, GAP, 0);
        add(namePanel, tfDescription, 1, 1, 1, 1, 100, 0,
            GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
            0, GAP, GAP, GAP);
        add(namePanel, aButton[DESCRIPTION], 2, 1, 1, 1, 0, 0,
            GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
            0, GAP, GAP, GAP);

        // Construct panel
        JPanel templPanel = new JPanel(gridBagLayout);
        templPanel.setBorder(BorderFactory.createTitledBorder(
            BorderFactory.createEtchedBorder(), " Default Template "));
        add(panel, templPanel, 0, 1, 1, 1, 100, 100,
            GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL,
            GAP, GAP, 0, GAP);

        add(templPanel, lblTemplate, 0, 0, 1, 1, 0, 0,
            GridBagConstraints.WEST, GridBagConstraints.NONE, 0, GAP, 0, 0);
        add(templPanel, comboTemplate, 1, 0, 1, 1, 100, 0,
            GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
            0, GAP, 0, GAP);
        add(templPanel, aButton[TEMPLATE], 2, 0, 1, 1, 0, 0,
            GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL,
            0, GAP, 0, GAP);
        add(templPanel, aButton[TEMPLATE_DESC], 1, 1, 2, 1, 0, 0,
            GridBagConstraints.EAST, GridBagConstraints.NONE,
            0, GAP, GAP, GAP);

        return panel;
    }

    private JPanel createTextTab() {
        JPanel panel = new JPanel(gridBagLayout);

        // Initialize components
        tfTextSize = new JTextField(6);
        tfTextSize.setHorizontalAlignment(JTextField.LEFT);
        JLabel lblTextSize = new JLabel("Font Size:");
        lblTextSize.setDisplayedMnemonic('S');
        lblTextSize.setLabelFor(tfTextSize);

        checkTextName = new JCheckBox("Show Name");
        checkTextName.setMnemonic('N');
        checkTextDesc = new JCheckBox("Show Description");
        checkTextDesc.setMnemonic('E');

        alstTextIndex = new JList[AbsElemGeom.NUM_SHOW];
        alstTextIndex[AbsElemGeom.SHOW_DATA] = new JList(SysConst.ssDataField);
        alstTextIndex[AbsElemGeom.SHOW_RESULT]=new JList(SysConst.ssResultField);

        JLabel[] alblTextIndex = new JLabel[AbsElemGeom.NUM_SHOW];
        alblTextIndex[AbsElemGeom.SHOW_DATA] =
            new JLabel("Data Fields to Display:");
        alblTextIndex[AbsElemGeom.SHOW_DATA].setDisplayedMnemonic('D');
        alblTextIndex[AbsElemGeom.SHOW_RESULT] =
            new JLabel("Results Fields to Display:");
        alblTextIndex[AbsElemGeom.SHOW_RESULT].setDisplayedMnemonic('R');
        for (int iCat = 0; iCat < AbsElemGeom.NUM_SHOW; iCat++) {
            alstTextIndex[iCat].setSelectionMode(
                ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
            alstTextIndex[iCat].setSelectedIndex(0);
            alblTextIndex[iCat].setLabelFor(alstTextIndex[iCat]);
        }

        aButton[TEXT] = new JButton("Replace Values");
        aButton[TEXT].setMnemonic('V');
        aButton[TEXT].addActionListener(this);

        // Construct panel
        JPanel subPanel = new JPanel(gridBagLayout);
        subPanel.setBorder(BorderFactory.createTitledBorder(
            BorderFactory.createEtchedBorder(), " Text "));
        add(panel, subPanel, 0, 0, 1, 1, 100, 100,
            GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH,
            GAP, GAP, GAP, GAP);

        add(subPanel, lblTextSize, 0, 0, 1, 1, 0, 0,
            GridBagConstraints.WEST, GridBagConstraints.NONE, 0, GAP, 0, 0);
        tfTextSize.setNextFocusableComponent(checkTextName);
        add(subPanel, tfTextSize, 1, 0, 1, 1, 1, 0,
            GridBagConstraints.WEST, GridBagConstraints.NONE, 0, GAP, 0, 0);

        add(subPanel, checkTextName, 0, 1, 2, 1, 1, 0,
            GridBagConstraints.WEST, GridBagConstraints.NONE, 0, GAP, 0, 0);
        add(subPanel, checkTextDesc, 0, 2, 2, 1, 1, 0,
            GridBagConstraints.WEST, GridBagConstraints.NONE, 0, GAP, 0, 0);

        aButton[TEXT].setNextFocusableComponent(comboZone);
        add(subPanel, aButton[TEXT], 2, 0, 2, 3, 0, 0,
            GridBagConstraints.NORTHEAST, GridBagConstraints.NONE,
            0, GAP, 0, GAP);

        alstTextIndex[AbsElemGeom.NUM_SHOW-1].setNextFocusableComponent(
            aButton[TEXT]);
        Dimension preferredSize = new Dimension(100, 10);
        for (int iCat = 0; iCat < AbsElemGeom.NUM_SHOW; iCat++) {
            JScrollPane scrollTextIndex = new JScrollPane(alstTextIndex[iCat]);
            scrollTextIndex.setPreferredSize(preferredSize);
            int iRight = (iCat == AbsElemGeom.NUM_SHOW-1 ? GAP : 0);
            add(subPanel, alblTextIndex[iCat], 2*iCat, 3, 2, 1, 1, 0,
                GridBagConstraints.WEST, GridBagConstraints.NONE,
                GAP, GAP, 0, iRight);
            add(subPanel, scrollTextIndex, 2*iCat, 4, 2, 1, 1, 1,
                GridBagConstraints.WEST, GridBagConstraints.BOTH,
                0, GAP, GAP, iRight);
        }

        return panel;
    }

    /**
     * This method is public as an implementation side effect.
     * do not call or override.
     */
    public void actionPerformed(ActionEvent evt) {
        Object source = evt.getSource();
        if (source == comboType) {
            // the component type changed
            DefaultComboBoxModel model =
                (DefaultComboBoxModel)comboTemplate.getModel();
            model.removeAllElements();
            int iSubList = SysConst.mapTypeToTemplType(
                SysConst.mapIndexToType(comboType.getSelectedIndex()));
            if (iSubList >= 0) {
                comboTemplate.setEnabled(true);
                aButton[TEMPLATE].setEnabled(true);
                aButton[TEMPLATE_DESC].setEnabled(true);

                int sz = Templates.nameLists[iSubList].size();
                for(int i = 0; i < sz; i++){
                    model.addElement(Templates.nameLists[iSubList].elementAt(i));
                }
            } else {
                comboTemplate.setEnabled(false);
                aButton[TEMPLATE].setEnabled(false);
                aButton[TEMPLATE_DESC].setEnabled(false);
            }

            return;
        }

        // Determine action
        int iAction;
        for (iAction = 0; iAction < aButton.length; iAction++) {
            if (source == aButton[iAction])
                break;
        }
        if (iAction == aButton.length)
            return; // Oops!

        // Retrieve information
        double dZone;
        int iType, iDisplayIndex = 0;
        //SysConst.MappedIndex field = null;

        int iValueIndex=-1; //index for adData[]
        double dValue = 0.0, dRange = 0.0;
        String sValue = null;
        AbsElem elemValue = null;
        int[][] aiIndex = null;
        try {
            dZone = comboZone.getSelectedZone();
            iType = SysConst.mapIndexToType(comboType.getSelectedIndex());
            if (iType == SysConst.TYPE_NONE) {
                JOptionPane.showMessageDialog(this,
                    "Component Type '[None]' is selected.");
                return;
            }
            if (iAction <= DATA_RANDOM) {
                // Retrieve field for all data actions
                iDisplayIndex = comboDataField.getSelectedIndex();
                if (iDisplayIndex == AbsElem.DATA_NONE) {
                    JOptionPane.showMessageDialog(this,
                        "Data Field '[None]' is selected.");
                    return;
                }
                iValueIndex =  SysConst.mapDataIndexFromDisplayToValue(iDisplayIndex);//SysConst.mapData(iDisplayIndex);
            }
            switch (iAction) {
                case DATA_REPLACE:
                    dValue = Double.parseDouble(tfDataReplace.getText());
                    break;
                case DATA_MULTIPLY:
                    iValueIndex = SysConst.mapDataIndexFromDisplayToValue(comboDataField.getSelectedIndex());
                    dValue = Double.parseDouble(tfDataMultiply.getText());
                    break;
                case DATA_ADD:
                    iValueIndex = SysConst.mapDataIndexFromDisplayToValue(comboDataField.getSelectedIndex());
                    dValue = Double.parseDouble(tfDataAdd.getText());
                    break;
                case DATA_RESTORE:
                case DATA_CUSTOMIZE:
                    iValueIndex = SysConst.mapDataIndexFromDisplayToValue(comboDataField.getSelectedIndex());
                    break;
                case DATA_RANDOM:
                    iValueIndex = SysConst.mapDataIndexFromDisplayToValue(comboDataField.getSelectedIndex());
                    dValue = Double.parseDouble(tfDataRandomMin.getText());
                    dRange =
                        Double.parseDouble(tfDataRandomMax.getText()) - dValue;
                    break;
                case NAME:
                    sValue = tfName.getText();
                    break;
                case DESCRIPTION:
                    sValue = tfDescription.getText();
                    break;
                case TEMPLATE:
                case TEMPLATE_DESC:
                    int iSubList = SysConst.mapTypeToTemplType(
                        SysConst.mapIndexToType(comboType.getSelectedIndex()));
                    int index = Templates.nameLists[iSubList].indexOf(
                        comboTemplate.getSelectedItem());
                    elemValue = (AbsElem)Templates.subLists[iSubList].
                        elementAt(index);
                    break;
                case TEXT:
                    dValue = Double.parseDouble(tfTextSize.getText());
                    aiIndex = new int[AbsElemGeom.NUM_SHOW][];
                    for (int iCat = 0; iCat < AbsElemGeom.NUM_SHOW; iCat++) {
                        aiIndex[iCat] = alstTextIndex[iCat].getSelectedIndices();
                        if (aiIndex[iCat].length == 0 || aiIndex[iCat][0] == 0){
                            // nothing or [None] is selected
                            aiIndex[iCat] = null;
                        }
                    }
                    // map indices
                    if (aiIndex[AbsElemGeom.SHOW_DATA] != null) {
                        int[] ai = aiIndex[AbsElemGeom.SHOW_DATA];
                        for (int i = 0; i < ai.length; i++) {
                            ai[i] = SysConst.
                                mapDataIndexFromDisplayToValue(ai[i]);
                        }
                    }
                    if (aiIndex[AbsElemGeom.SHOW_RESULT] != null) {
                        int[] ai = aiIndex[AbsElemGeom.SHOW_RESULT];
                        for (int i = 0; i < ai.length; i++) {
                            ai[i] = SysConst.
                                mapResultIndexFromDisplayToValue(ai[i]);
                        }
                    }
                    break;
            }
        } catch(ZoneComboBox.ZoneException e) {
            JOptionPane.showMessageDialog(this,
                "'" + e.getMessage() + "' is not a valid zone.");
            return;
        } catch(NumberFormatException e) {
            JOptionPane.showMessageDialog(this,
                "'" + e.getMessage() + "' is not a valid number.");
            return;
        }

        // Do action
        int iCountOk = 0, iCountBad = 0;
        for (int i = 0; i < Sys.elemList.size(); i++) {
            AbsElem elem = (AbsElem)Sys.elemList.elementAt(i);
            AbsElemGeom geom = elem.getElemGeomObj();

            if (Zone.getZoneFits(dZone, elem) &&
                (iType == SysConst.TYPE_ALL || iType == elem.getType())) {
                try {
                    switch (iAction) {
                        case DATA_REPLACE:
                            elem.setData( iValueIndex, dValue);
                            elem.setCustomizedFlag(iValueIndex, true);
                            if (iValueIndex == AbsElem.DATA_ZONE) {
                                Sys.prjInfo.addZoneIfUnexisted(dValue, null);
                            }
                            break;
                        case DATA_MULTIPLY:
                            elem.multiplyData(iValueIndex, dValue);
                            elem.setCustomizedFlag(iValueIndex, true);
                            if (iValueIndex == AbsElem.DATA_ZONE) {
                                Sys.prjInfo.addZoneIfUnexisted(elem.
                                    getData(iValueIndex), null);
                            }
                            break;
                        case DATA_ADD:
                            elem.addToData(iValueIndex, dValue);
                            elem.setCustomizedFlag(iValueIndex, true);
                            if (iValueIndex == AbsElem.DATA_ZONE) {
                                Sys.prjInfo.addZoneIfUnexisted(elem.
                                    getData(iValueIndex), null);
                            }
                            break;
                        case DATA_RESTORE:
                            AbsElem dftTemp = elem.getDftTemp();
                            if (dftTemp == null) {
                                iCountBad++;
                                continue;
                            }
                            dValue = dftTemp.getData(iValueIndex);
                            elem.setData(iValueIndex, dValue);
                            elem.setCustomizedFlag(iValueIndex, false);
                            break;
                        case DATA_CUSTOMIZE:
                            elem.setCustomizedFlag(iValueIndex, true);
                            break;
                        case DATA_RANDOM:
                            double dNewValue = dRange * Math.random() + dValue;
                            elem.setData(iValueIndex, dNewValue);
                            elem.setCustomizedFlag(iValueIndex, true);
                            if (iValueIndex == AbsElem.DATA_ZONE) {
                                Sys.prjInfo.addZoneIfUnexisted(dNewValue, null);
                            }
                            break;
                        case NAME:
                            geom.setName(sValue);
                            break;
                        case DESCRIPTION:
                            geom.setDesc(sValue);
                            break;
                        case TEMPLATE_DESC:
                            geom.setDesc(elemValue.getElemGeomObj().getDesc());
                            // fall through
                        case TEMPLATE:
                            elem.setDftTemp(elemValue);
                            Templates.copyAllDataFromTemp(elem, elemValue);
                            break;
                        case TEXT:
                            elem.setData(AbsElem.DATA_FONT_SIZE, dValue);
                            elem.setFlag(AbsElem.DATA_FONT_SIZE, 1);
                            geom.setShowName(checkTextName.isSelected());
                            geom.setShowDesc(checkTextDesc.isSelected());
                            for (int cat = 0; cat < AbsElemGeom.NUM_SHOW; cat++)
                                geom.setShowIndex(cat, aiIndex[cat]);
                            break;
                    }
                    iCountOk++;
                } catch(IllegalArgumentException e) {
                    iCountBad++;
                }
            }
        }
        String sMessage = "" + iCountOk + " component" +
            (iCountOk != 1 ? "s" : "") + " adjusted";
        if (iCountBad > 0) {
            sMessage += ", " + iCountBad + " operation" +
                (iCountBad > 1 ? "s" : "") + " failed";
        }
        JOptionPane.showMessageDialog(this, sMessage + ".");
    }

    /*======================================
    Implement WindowListener interfaces
    ======================================*/
    public void windowOpened(WindowEvent evt) { }
    public void windowClosed(WindowEvent evt) { }
    public void windowIconified(WindowEvent evt) { }
    public void windowDeiconified(WindowEvent evt) { }
    public void windowActivated(WindowEvent evt) { }
    public void windowDeactivated(WindowEvent evt) {
        mainFrame.mainPanel.setNeedRedraw(true);
        mainFrame.mainPanel.repaint();
    }
    public void windowClosing(WindowEvent evt) {
        mainFrame.mainPanel.setNeedRedraw(true);
        mainFrame.mainPanel.repaint();
        hide();
    }
}